/*
 * Created on Nov 23, 2005
 */
package net.amsoft.iservice.util;

import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import net.amsoft.iservice.util.IServiceConstants;

import org.apache.log4j.Logger;

/**
 * @author RahulJoshi
 * 
 */
public class EmailService extends Thread {
    private static Logger oLog = Logger.getLogger(EmailService.class);

    private static EmailService instance = null;
    private static Properties oProp;

    private String sSubject;
    private String sBody;
    private String sFromAddress;
    private ArrayList lRecipientList;
    private String sReplyToAddress;

    static {
        String host = IServiceConstants.ISERVICE_BUNDLE
                .getString(IServiceConstants.SMTP_HOST);
        if (host == null) {
            oLog.fatal("EmailService: Email server not found. Quiting.. ");
            throw new RuntimeException("EmailService: Email server not found");
        }
        oProp = new Properties();
        oProp.put(IServiceConstants.SMTP_HOST, host);
    }

    public EmailService() {

    }
    /**
     * getInstance() returns the instance of the <code>EmailService</code>
     * singleton.
     * 
     * @return <code>EmailService</code> singleton.
     */
    public final static synchronized EmailService getInstance() {
        if (instance == null) {
            instance = new EmailService();
        }
        return instance;
    }

    public final void sendMail() {
        this.start();
    }// end of sendMail()

    public void setReceipientList(ArrayList receipientList) {
        lRecipientList = receipientList;
    }
    public void setBody(String body) {
        sBody = body;
    }
    public void setFromAddress(String fromAddress) {
        sFromAddress = fromAddress;
    }
    public void setReplyToAddress(String replyToAddress) {
        sReplyToAddress = replyToAddress;
    }
    public void setSubject(String subject) {
        sSubject = subject;
    }

    protected final Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }

    private final void writeObject(ObjectOutputStream out)
            throws java.io.IOException {
        throw new java.io.IOException("Object cannot be serialized");
    }

    public void run() {
        try {
            InternetAddress[] replyTo = new InternetAddress[1];
            Session session = Session.getInstance(oProp);
            MimeMessage mimeMessage = new MimeMessage(session);
            try {
                replyTo[0] = new InternetAddress(sReplyToAddress);
            } catch (AddressException e) {
                oLog.warn("run(): Reply to Address is not valid, setting " +
                                "to from address.=" + sReplyToAddress);
                replyTo[0] = new InternetAddress(sFromAddress);
            }
            mimeMessage.setReplyTo(replyTo);
            mimeMessage.setFrom(new InternetAddress(sFromAddress));
            mimeMessage.setSubject(sSubject, "UTF-8");
            mimeMessage.setText(sBody, "UTF-8");
            oLog.debug("run(): Email object properties set");
            
            for (int counter = 0; counter < lRecipientList.size(); counter++) {
                mimeMessage.addRecipient(Message.RecipientType.TO,
                        new InternetAddress((String) lRecipientList
                                .get(counter)));
            }
            Transport.send(mimeMessage);
            oLog.info("run(): E-mail with following details has been sent:" + debug(null));
        } catch (AddressException e) {
            oLog.fatal("run(): Email NOT sent. From Address is not valid=" + sFromAddress);
        } catch(MessagingException me){
            oLog.fatal("run(): Email NOT sent. E-mail properties could not be " +
                    "set. " + debug(null));
        }catch (Exception e) {
            oLog.fatal("run(): E-Mail could not be sent. Details: "
                    + debug(null));
        }
    }

    public String debug(String pattern) {
        if (pattern == null) {
            pattern = "";
        }
        String sDebugMsg = pattern + ": SUB=" + sSubject + ", BODY=" + sBody
                + ", FROM=" + sFromAddress + ", REPLYTO=" + sReplyToAddress;
        for (int i = 0; i < lRecipientList.size(); i++) {
            sDebugMsg += ", TO[" + i + "]=" + lRecipientList.get(i);
        }
        oLog.debug(sDebugMsg);
        return sDebugMsg;
    }
}
